
/*******************************************************************************
 * Copyleft (c) 2021 Kcode
 *
 * @file    wav.c
 * @brief   实现对wav格式文件的操作
 * @author  K
 * @version 0.0.1
 * @date    2021-08-05
 * @license MulanPSL-1.0
 *
 * 文件修改历史：
 * <时间>       | <版本>    | <作者>  | <描述>
 * 2021-08-05   | v0.0.1    | Kcode   | 实现对wav格式文件的操作
 * -----------------------------------------------------------------------------
 ******************************************************************************/

#include "types.h"

extern void nand_read(unsigned int addr, unsigned char *buf, unsigned int len);

/**
 * @brief wav文件的文件头信息
 */
typedef struct RIFF_HEADER
{
    char szRiffID[4];       /**< 标识：'R','I','F','F' */
    DWORD dwRiffSize;       /**< 文件大小(减去ID和Size所占用的字节数) */
    char szRiffFormat[4];   /**< 标识：'W','A','V','E' */
}RIFF_HEADER_S, *RIFF_HEADER_P;

/**
 * @brief wav文件的具体格式信息
 */
typedef struct WAVE_FORMAT
{
    WORD wFormatTag;            /**< 编码方式，一般为0x0001 */
    WORD wChannels;             /**< 声道数目，1-单声道，2-双声道 */
    DWORD dwSamplesPerSec;      /**< 采样频率 */
    DWORD dwAvgBytesPerSec;     /**< 每秒所需字节数 */
    WORD wBlockAlign;           /**< 每个采样需要的字节数 */
    WORD wBitsPerSample;        /**< 每个采样需要的bit数 */
}WAVE_FORMAT_S, *WAVE_FORMAT_P;

/**
 * @brief wav文件的格式信息
 */
typedef struct FMT_BLOCK
{
    char  szFmtID[4];       /**< 标识：'f','m','t',' ' */
    DWORD  dwFmtSize;       /**< 格式数据的大小 */
    WAVE_FORMAT_S wavFormat;  /**< 存储具体格式的结构体 */
}FMT_BLOCK_S, *FMT_BLOCK_P;

/**
 * @brief wav文件的数据信息
 */
typedef struct DATA_BLOCK
{
    char szDataID[4];       /**< 标识：'d','a','t','a' */
    DWORD dwDataSize;       /**< 视频数据的大小，后面接着的就是视频数据 */
}DATA_BLOCK_S, *DATA_BLOCK_P;

/*!
 * @brief  读出wav数据
 *
 * @param [in]   wav_buf 读取的wav格式数据所要存储的位置
 * @param [out]  fs 采样率
 * @param [out]  channels 通道数
 * @param [out]  bits_per_sample 每个采样值占据位数
 * @param [out]  wav_size wav每个采样值占据位数
 *
 * @note  需要事先使用uboot把wav文件烧写在NAND的0x60000地址
 *
 * @return void
 */
void read_wav(unsigned int wav_buf, int *fs, int *channels, 
                            int *bits_per_sample, int *wav_size)
{
    FMT_BLOCK_P fmtblk;
    DATA_BLOCK_P datablk;
    
    /*!
     * 从NAND的0x60000地址中把wav数据读出来
     */
    nand_read(0x60000, (unsigned char *)wav_buf, 0x200000);

    /*!
     * 分析wav文件的信息，读出采样率，通道数，每个采样值占据位数，计算每个采样值占据位数
     */
    fmtblk            = (FMT_BLOCK_P)(wav_buf +  sizeof(RIFF_HEADER_S));
    *fs               = fmtblk->wavFormat.dwSamplesPerSec;
    *channels         = fmtblk->wavFormat.wChannels;
    *bits_per_sample = fmtblk->wavFormat.wBitsPerSample;

    datablk    = (DATA_BLOCK_P)&fmtblk[1];
    *wav_size = datablk->dwDataSize;
}

